package code;

import main.ErrorException;
import define.Common;
import define.Config;
import define.ErrorDefine;
import define.ReferenceExtraType;
import define.ReferenceType;

public class Type
{
	private ReferenceType m_type;
	private ReferenceExtraType m_extraType;
	private String m_text;
	private Type[] m_children;
	
	public Type(String text) throws ErrorException
	{
		m_children = null;
		m_text = Common.removeBlank(text);
		if(m_text.length() == 0)
		{
			throw new ErrorException(ErrorDefine.E_REFERENCE_NULL_ERROR, Config.NO_POSITION);
		}
		makeType();
		if(m_type != ReferenceType.E_REFERENCE_RT && m_type != ReferenceType.E_CUSTOM_RT)
		{
			m_text = null;
		}
	}
	
	private void makeType() throws ErrorException
	{
		m_extraType = ReferenceExtraType.checkExtraTypeByEnd(m_text.charAt(m_text.length() - 1));
		if(m_extraType == null)
		{
			m_type = ReferenceType.getReferenceType(m_text);
		}
		else
		{
			if(m_extraType.isOnlyEnd())
			{
				m_children = new Type[1];
				m_children[0] = new Type(m_text.substring(0, m_text.length() - 1));
			}
			else
			{
				if(m_text.charAt(0) != m_extraType.getStart())
				{
					throw new ErrorException(ErrorDefine.E_TYPE_NOT_MATCH_ERROR, m_text, Config.NO_POSITION);
				}
				int index = m_text.indexOf(Config.CODE_TYPE_SPLIT);
				if(m_extraType == ReferenceExtraType.E_LIST_RET && index >= 0)
				{
					if(index == 1 || index == m_text.length() - 2)
					{
						throw new ErrorException(ErrorDefine.E_REFERENCE_NULL_ERROR, Config.NO_POSITION);
					}
					m_extraType = ReferenceExtraType.E_MAP_RET;
					m_children = new Type[2];
					m_children[0] = new Type(m_text.substring(1, index));
					m_children[1] = new Type(m_text.substring(index + 1, m_text.length() - 1));
				}
				else
				{
					m_children = new Type[1];
					m_children[0] = new Type(m_text.substring(1, m_text.length() - 1));
				}
			}
		}
	}
	
	public ReferenceType getType()
	{
		return m_type;
	}
	
	public ReferenceExtraType getExtraType()
	{
		return m_extraType;
	}
	
	public String getText()
	{
		return m_text;
	}
	
	public Type[] getChildren()
	{
		return m_children;
	}
	
	public boolean isSimpleType()
	{
		if(m_extraType != null)
		{
			return m_extraType == ReferenceExtraType.E_POINT_RET || m_extraType == ReferenceExtraType.E_REFERENCE_RET || m_extraType == ReferenceExtraType.E_ARRAY_RET;
		}
		return m_type != ReferenceType.E_REFERENCE_RT;
	}
	
	public boolean isNeedSetValue()
	{
		return isSimpleType() && m_extraType != ReferenceExtraType.E_ARRAY_RET;
	}
}
